package com.ddx.service.impl;


import com.ddx.check.CheckUserParamValidate;
import com.ddx.common.enums.*;
import com.ddx.common.exception.BusinessException;
import com.ddx.common.exception.ResultModel;
import com.ddx.common.redis.RedisService;
import com.ddx.common.util.*;
import com.ddx.dao.*;
import com.ddx.dto.UserDto;
import com.ddx.enums.ShortVideoStatusEnum;
import com.ddx.enums.SmsCodeEnum;
import com.ddx.pojo.*;
import com.ddx.service.*;
import io.netty.util.internal.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author dudianbo
 * @ClassName: UserServiceImpl
 * @Description: 用户信息
 * @date 2018/4/18
 */
@Service
public class UserServiceImpl implements IUserService {

    private static Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    @Autowired
    UserMapper userMapper;
    @Autowired
    ShoppingAccountMapper shoppingAccountMapper;
    @Autowired
    IUserTokenService iUserTokenService;

    @Autowired
    RedisService redisService;

    @Autowired
    ShortVideoService shortVideoService;

    @Autowired
    UserFollowMapper userFollowMapper;
    @Autowired
    ICommonService iCommonService;
    @Value("${fastdfs.server}")
    String fastdfsServer;
    @Autowired
    ShoppingStoreMapper storeMapper;
    @Autowired
    IncomeFlowMapper incomeFlowMapper;
    @Autowired
    IAccountService iAccountService;
    /**
     * 用户登录接口
     *
     * @param userDto
     */
    @Override
    public Map<String, String> login(UserDto userDto) throws Exception {
        logger.info("登陆接口传入参数userDto={}", userDto);
        //进行参数校验
        CheckUserParamValidate.checkLogin(userDto);
        //根据手机号查出当前用户密码
        User record = new User();
        record.setMobile(userDto.getMobile());
        List<User> list = userMapper.selectByRecord(record);
        if (list == null || list.size() == 0) {
            logger.error("当前用户{}未注册", userDto.getMobile());
            throw new BusinessException(ErrorCode.ACCOUNT_ERROR_303);
        }
        User user = list.get(0);
        if (!userDto.getPassword().equalsIgnoreCase(user.getPassword())) {
            logger.error("当前用户{}用户名与密码{}不匹配", userDto.getMobile(), userDto.getPassword());
            throw new BusinessException(ErrorCode.ACCOUNT_ERROR_304);
        }
        String token = iUserTokenService.createToken(user.getXxNumber(), userDto.getDevicecId() + System.currentTimeMillis(), Platform.APP);
        Map<String, String> map = new HashMap<>();
        map.put("userId", user.getId().toString());
        map.put("token", token);
        return map;
    }

    @Override
    public Map<String, String> smsLogin(UserDto userDto) throws Exception {
        logger.info("验证码接口传入参数userDto={}", userDto);
        //进行参数校验
        CheckUserParamValidate.checkSmsLogin(userDto);
        //校验验证码
        iCommonService.verifiSmsCode(userDto.getSmsCode(), userDto.getMobile(), SmsCodeEnum.LOGIN.getValue());
        //根据手机号查用户
        User record = new User();
        record.setMobile(userDto.getMobile());
        List<User> list = userMapper.selectByRecord(record);
        if (list == null || list.size() == 0) {
            //当前用户未注册，需要创建用户
//            return iUserCreatUserService.createUser(userDto);
        }
        User user = list.get(0);
        String token = iUserTokenService.createToken(user.getXxNumber(), userDto.getDevicecId() + System.currentTimeMillis(), Platform.APP);
        Map<String, String> map = new HashMap<>();
        map.put("userId", user.getId().toString());
        map.put("token", token);
        return map;
    }

    /**
     * 用户注册接口
     *
     * @param userDto
     */
    @Override
    public Map<String, String> register(UserDto userDto) throws Exception {
        logger.info("用户注册入参userDto={}", userDto);
        //进行参数校验
        CheckUserParamValidate.checkRegister(userDto);
        //校验验证码
        iCommonService.verifiSmsCode(userDto.getSmsCode(), userDto.getMobile(), SmsCodeEnum.REGISTER.getValue());
        //添加user表
        User user=new User();
        user.setMobile(userDto.getMobile());
        user.setPassword(userDto.getPassword());

        if (userDto.getSex()!=null)
            user.setSex(userDto.getSex());
        if (!StringUtil.isNullOrEmpty(userDto.getName()))
            user.setName(userDto.getName());
        user.setXxNumber(String.valueOf(System.currentTimeMillis()));
        user.setIsDeleted(UserStatus.NORMAL.getValue());
        try {
            userMapper.insertSelective(user);
        }catch (DuplicateKeyException e){
            logger.error("注册时异常",e);
            throw new BusinessException(ErrorCode.ESSAGE_ERROR_M410);
        }
        List<User> users=userMapper.selectByRecord(user);
        if(users==null||users.size()==0){
            throw new BusinessException(ErrorCode.BUSSINESS_ERROR_201);
        }
        String userId=users.get(0).getId().toString();
        //添加账户表
        ShoppingAccount shoppingAccount = new ShoppingAccount();
        String accountNo = "1" + DataUtil.addZeroStr(userId, 7);
        shoppingAccount.setAccountNo(accountNo);
        shoppingAccount.setUserId(userId);
        shoppingAccount.setTotalAmount(BigDecimal.ZERO);
        shoppingAccount.setFrozenAmount(BigDecimal.ZERO);
        shoppingAccount.setAccountType(1);
        shoppingAccount.setInterestTotal(BigDecimal.ZERO);
        shoppingAccount.setStatus(Status.NORMAL.getCode());
        shoppingAccountMapper.insertSelective(shoppingAccount);

        String token = iUserTokenService.createToken(user.getXxNumber(), userDto.getDevicecId() + System.currentTimeMillis(), Platform.APP);
        Map<String,String> map=new HashMap<>();
        map.put("userId",userId);
        map.put("token",token);
        return map;
    }
//    /**
//     * 找回密码接口  方法已删除
//     *
//     * @param userDto
//     */
//    @Override
//    @Deprecated
//    public String findPsd(UserDto userDto) throws Exception {
//        logger.info("找回密码接口入参userDto={}", userDto);
//        //校验验证码
//        iCommonService.verifiSmsCode(userDto.getSmsCode(), userDto.getMobile(), TemplateType.FINDPASSWORD.getCode());
//        //TODO 设置超时时长
//        String uuid = UUID.randomUUID().toString();
//        logger.info("找回密码接口key={},sign={}", RedisKey.FIND_PWD_SIGN + userDto.getMobile(), uuid);
//        redisService.set(RedisKey.FIND_PWD_SIGN + userDto.getMobile(), uuid);
//        return uuid;
//    }

    /**
     * 重置密码接口
     *
     * @param userDto
     */
    @Override
    public void resetPsd(UserDto userDto) throws Exception {
        logger.info("重置密码接口入参userDto={}", userDto);
        CheckUserParamValidate.checkResetPsd(userDto);
        iCommonService.verifiSmsCode(userDto.getSmsCode(), userDto.getPhoneNum(), userDto.getType());
        //根据手机号查用户
        User record = new User();
        record.setMobile(userDto.getMobile());
        List<User> list = userMapper.selectByRecord(record);
        if (list == null || list.size() == 0) {
            logger.error("当前用户{}未注册", userDto.getMobile());
            throw new BusinessException(ErrorCode.ACCOUNT_ERROR_303);
        }
        User user = new User();
        user.setMobile(userDto.getPhoneNum());
        user.setPassword(userDto.getPassword());
        userMapper.updateByMobile(user);
    }

//    /**
//     * 修改密码接口
//     *
//     * @param userDto
//     */
//    @Override
//    public void updatePsd(UserDto userDto) throws Exception {
//        logger.info("修改密码接口入参userDto={}", userDto);
//        //进行参数校验
//        CheckUserParamValidate.checkUpdatePsd(userDto);
//
//        User record = userMapper.selectByPrimaryKey(userDto.getId());
//        if (record == null) {
//            throw new BusinessException(ErrorCode.ACCOUNT_ERROR_303);
//        }
//        if (!record.getPasswordHash().equals(userDto.getOldPsd())) {
//            throw new BusinessException(ErrorCode.ESSAGE_ERROR_M409);
//        }
//        User user = new User();
//        user.setId(userDto.getId());
//        user.setPasswordHash(userDto.getPassword());
//        userMapper.updateByPrimaryKeySelective(user);
//    }

//    @Override
//    public void newUpdatePsd(UserDto userDto) throws Exception {
//        logger.info("修改密码接口newUpdatePsd 入参userDto={}", userDto);
//        //进行参数校验
//        CheckUserParamValidate.checkNewUpdatePsd(userDto);
//        User record = userMapper.selectByPrimaryKey(userDto.getId());
//        if (record == null) {
//            throw new BusinessException(ErrorCode.ACCOUNT_ERROR_303);
//        }
//        iCommonService.verifiSmsCode(userDto.getSmsCode(), record.getMobile(), TemplateType.UPDATE_LOGIN_PASS.getCode());
//
//        User user = new User();
//        user.setId(userDto.getId());
//        user.setPasswordHash(userDto.getPassword());
//        userMapper.updateByPrimaryKeySelective(user);
//    }

    @Override
    public void verifyUser(String userId, String token, Platform platform) throws Exception {
        logger.debug("用户登陆校验:userId={},token={}", userId, token);
        User user = userMapper.selectByPrimaryKey(Integer.parseInt(userId));
        if (user == null) {
            throw new BusinessException(ErrorCode.LOGIN_ERROR_401);
        }

        UserStatus userStatus = UserStatus.getUserStatus(user.getIsDeleted());
        if (!userStatus.equals(UserStatus.NORMAL)) {
            throw new BusinessException(ErrorCode.LOGIN_ERROR_403);
        }

        // 获取用户token
        String userToken = iUserTokenService.getToken(user.getXxNumber(), platform);
        if (StringUtils.isBlank(userToken)) {
            throw new BusinessException(ErrorCode.LOGIN_ERROR_401);
        }
        if (!userToken.equals(token)) {
            throw new BusinessException(ErrorCode.LOGIN_ERROR_405);
        }
    }

//    /**
//     * 发送验证码
//     *
//     * @param userDto
//     */
//    @Override
//    public void sendSms(UserDto userDto) throws Exception {
//        logger.info("发送验证码查询 参数 userDto {} ", userDto);
//        //参数校验
//        CheckUserParamValidate.checkSendSms(userDto);
//        SmsContentDto smsContentDto = new SmsContentDto();
//        smsContentDto.setMoblie(userDto.getMobile());
//        //验证码类型
//        smsContentDto.setTemplateType(userDto.getType());
//        // 如果类型是  找回密码  先判断此手机号是否存在
//        if (TemplateType.getTemplateType(userDto.getType()) == TemplateType.FINDPASSWORD) {
//            User selectByMobile = new User();
//            selectByMobile.setMobile(userDto.getMobile());
//            List<User> users = userMapper.selectByRecord(selectByMobile);
//            if (users == null || users.size() == 0) { //手机号不存在
//                throw new BusinessException(ErrorCode.ACCOUNT_ERROR_303);
//            }
//        }
//        // 注册类型 先检测用户是否注册
//        if (TemplateType.getTemplateType(userDto.getType()) == TemplateType.REGISTER) {
//            User selectByMobile = new User();
//            selectByMobile.setMobile(userDto.getMobile());
//            List<User> users = userMapper.selectByRecord(selectByMobile);
//            if (users != null && users.size() > 0) { //手机号不存在
//                throw new BusinessException(ErrorCode.ESSAGE_ERROR_M410);
//            }
//        }
//
//        //根据模板生成短信内容
//        String messageContext = iMsgSendService.createSmsContent(smsContentDto);
//        if (StringUtils.isNotBlank(messageContext)) {
//            //发送短信
//            iMsgSendService.sendSmsByInfo(messageContext, userDto.getMobile(), userDto.getType());
//        }
//    }


    @Override
    public void signOut(String userId) {
        User user = userMapper.selectByPrimaryKey(Integer.parseInt(userId));
        if (Objects.nonNull(user)) {
            iUserTokenService.deleteToken(user.getMobile(), Platform.APP);
        }
    }

    @Override
    public User getUserInfo(String userId) {
        User user = userMapper.selectByPrimaryKey(Integer.parseInt(userId));
        user.setPassword(null);
        if(StringUtils.isNotBlank(user.getHeadImage())) {
            if (user.getHeadImage().contains("http")) {
                user.setHeadImage(user.getHeadImage());
            } else {
                user.setHeadImage(fastdfsServer + user.getHeadImage());
            }
        }

        ShoppingStore shoppingStore = storeMapper.selectByUserId(Integer.parseInt(userId));
        if (Objects.nonNull(shoppingStore)) {
            user.setSupplier(true);
        }
        return user;
    }

    @Override
    public void saveUserInfo(User user) {
        user.setHeadImage(null);
        userMapper.updateByPrimaryKeySelective(user);
    }

    @Override
    public ResultModel getUserCenterInfo(String masterUserId, String guestUserId) {
        logger.info("查看个人中心参数masterUserId={}，guestUserId={}",masterUserId,guestUserId);
        if(Objects.isNull(masterUserId)){
            return ResultModel.getErrorInstance("请先登录");
        }
        String finalUserId;
        boolean watchOtherPeople = !StringUtils.isEmpty(guestUserId) && Integer.parseInt(masterUserId) != Integer.parseInt(guestUserId);
        if (watchOtherPeople) {
            //查看别人
            finalUserId = guestUserId;
        } else {
            //查看自己
            finalUserId = masterUserId;
        }
        User user = getUserInfo(finalUserId);
        ShortVideo shortVideo = new ShortVideo();
        shortVideo.setUserId(Integer.parseInt(finalUserId));
        //公开视频
        shortVideo.setStatus(ShortVideoStatusEnum.PUBLIC.getValue());
        List<ShortVideo> publicSVList = shortVideoService.getListByRecord(shortVideo);

        //喜欢的视频
        List<ShortVideo> userLikeSVList = shortVideoService.getUserLikeSV(finalUserId);

        //统计我关注的人数
        int meFollow = userFollowMapper.countByFollowId(Integer.parseInt(finalUserId));

        //统计我的粉丝人数
        int followMe = userFollowMapper.countByUserId(Integer.parseInt(finalUserId));

        ResultModel resultModel = ResultModel.getSuccessInstance();
        Map<String, Object> map = new HashMap<>();
        map.put("userInfo", user);
        map.put("meFollow", followMe);
        map.put("followMe", meFollow);
        map.put("publicSVCount", publicSVList.size());
        map.put("publicSVList", publicSVList);
        map.put("userLikeSVCount", userLikeSVList.size());
        map.put("userLikeSVList", userLikeSVList);
        map.put("follow", false);
        map.put("privateSVCount", 0);
        map.put("privateSVList", new ArrayList<>());
        if (watchOtherPeople) {
            //是否已经关注别人
            UserFollow userFollow = userFollowMapper.selectByUserIdAndFollowId(Integer.parseInt(masterUserId), Integer.parseInt(guestUserId));
            map.put("status", "other");
            map.put("follow", !Objects.isNull(userFollow));
        } else {
            shortVideo.setStatus(ShortVideoStatusEnum.PRIVATE.getValue());
            List<ShortVideo> privateSVList = shortVideoService.getListByRecord(shortVideo);
            map.put("privateSVCount", privateSVList.size());
            map.put("privateSVList", privateSVList);
            map.put("status", "me");
        }
        logger.info("个人中心返回接口map={}",JsonUtil.objectToJson(map));
        resultModel.setData(map);
        return resultModel;
    }

    /**
     * 编辑用户资料
     */
	@Override
	public void editUserInfo(User user)  throws Exception{
		AssertUtil.isNotNull(user.getId(), "请登录");
		userMapper.updateByPrimaryKeySelective(user);
	}

    @Override
    public Map<String, String> thirtLogin(Map<String, Object> map) throws Exception{
	    logger.info("第三方登录入参map={}", JsonUtil.objectToJson(map));
        AssertUtil.isNotNull(map.get("type"), "第三方类型为空");
        AssertUtil.isNotNull(map.get("imageUrl"), "头像url为空");
        AssertUtil.isNotNull(map.get("name"), "用户名为空");
        AssertUtil.isNotNull(map.get("sex"), "用户性别为空");
//        AssertUtil.isNotNull(map.get("province"), "用户省份为空");
//        AssertUtil.isNotNull(map.get("city"), "用户地级市为空");
        AssertUtil.isNotNull(map.get("openid"), "用户openid为空");
        User user=new User();
        User add=new User();
        String openid=map.get("openid").toString();
        if(ThirtType.WX.getValue().equals(map.get("type").toString())){
            user.setWxId(openid);
            add.setWxId(openid);
        }else if(ThirtType.QQ.getValue().equals(map.get("type").toString())){
            user.setQqId(openid);
            add.setQqId(openid);
        }else if(ThirtType.WEIBO.getValue().equals(map.get("type").toString())){
            user.setWeiboId(openid);
            add.setQqId(openid);
        }
        String userId="";
        String xxNumber="";
        List<User> users=userMapper.selectByRecord(user);
        if(users==null||users.size()==0){
            add.setHeadImage(map.get("imageUrl").toString());
            add.setName(map.get("name").toString());
            add.setSex(Integer.parseInt(map.get("sex").toString()));
            if(map.get("city")!=null) {
                add.setCity(DataUtil.unicodeToCn(map.get("city").toString()));
            }
            if(map.get("province")!=null) {
                add.setProvince(DataUtil.unicodeToCn(map.get("province").toString()));
            }
            add.setXxNumber(String.valueOf(System.currentTimeMillis()));
            add.setIsDeleted(UserStatus.NORMAL.getValue());
            userMapper.insertSelective(add);
            List<User> list=userMapper.selectByRecord(user);
            userId=list.get(0).getId().toString();
            xxNumber=list.get(0).getXxNumber();
            //添加账户表
            ShoppingAccount shoppingAccount = new ShoppingAccount();
            String accountNo = "1" + DataUtil.addZeroStr(userId, 7);
            shoppingAccount.setAccountNo(accountNo);
            shoppingAccount.setUserId(userId);
            shoppingAccount.setTotalAmount(BigDecimal.ZERO);
            shoppingAccount.setFrozenAmount(BigDecimal.ZERO);
            shoppingAccount.setAccountType(1);
            shoppingAccount.setInterestTotal(BigDecimal.ZERO);
            shoppingAccount.setStatus(Status.NORMAL.getCode());
            shoppingAccountMapper.insertSelective(shoppingAccount);
        }else{
            userId=users.get(0).getId().toString();
            xxNumber=users.get(0).getXxNumber();
        }
        String token = iUserTokenService.createToken(xxNumber,System.currentTimeMillis()+"", Platform.APP);
        Map<String,String> returnMap=new HashMap<>();
        returnMap.put("userId",userId);
        returnMap.put("token",token);
        return returnMap;
    }

    @Override
    public String updateImage(String userId, MultipartFile file) throws Exception {
        AssertUtil.isNotNull(userId, "请登录");
        String url=FastDFSClient.uploadFileByByteAndGroup(file.getBytes(),"group1");
        User update=new User();
        update.setId(Integer.parseInt(userId));
        update.setHeadImage(url);
        userMapper.updateByPrimaryKeySelective(update);
        return fastdfsServer+url;
    }

    @Override
    @Transactional
    public Map<String, Object> signIn(String userId) {
	    logger.info("我的签到入参userid={}",userId);
	    IncomeFlow incomeFlow=new IncomeFlow();
        incomeFlow.setUserId(userId);
        incomeFlow.setType(1);
        incomeFlow.setAccountDate(DateUtil.format(new Date(),DateUtil.YYYYMMDD));
        List<IncomeFlow> list=incomeFlowMapper.selectByRecord(incomeFlow);
        if(list!=null&&list.size()>0){
            throw new BusinessException(ErrorCode.ACCOUNT_ERROR_308);
        }
        incomeFlow.setAccountDate(null);
        List<IncomeFlow> sign=incomeFlowMapper.selectByRecord(incomeFlow);
        Integer days=sign.size()+1;
        //增加多币
        String orderId=UUID.randomUUID().toString();
        Transaction transaction=new Transaction();
        transaction.setUserId(userId);
        transaction.setAccountType(1);
        transaction.setAmount(new BigDecimal(days));
        transaction.setOrderId(orderId);
        iAccountService.increase(transaction);
        //增加积分
        User user=new User();
        user.setId(Integer.parseInt(userId));
        user.setTotalPoint(days);
        userMapper.updatePoint(user);
        incomeFlow.setAccountDate(DateUtil.format(new Date(),DateUtil.YYYYMMDD));
        incomeFlow.setContent(days+"积分+"+days+"多币");
        incomeFlow.setOrderId(orderId);
        incomeFlowMapper.insertSelective(incomeFlow);
        Map<String, Object> map=new HashMap<>();
        map.put("signDays",days);
        map.put("point",days);
        map.put("amount",days);
        return map;
    }

    @Override
    public void realNameAuth(UserDto userDto) {
	    logger.info("实名认证参数{}",userDto);
	    CheckUserParamValidate.checkRealNameAuth(userDto);
        iCommonService.verifiSmsCode(userDto.getSmsCode(), userDto.getPhoneNum(), SmsCodeEnum.REAL_NAME_AUTH.getValue());
        userMapper.updateByPrimaryKeySelective(userDto);

    }
}
